﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using Rsa.DataAccess;
using Rsa.DataAccess.Models;
using Rsa.Util;
using System.Configuration;

namespace Rsa.Security {
    public class RsaMembershipProvider : MembershipProvider {
        #region "Private Members"
        private bool enablePasswordReset;
        private bool enablePasswordRetrieval;
        private bool requiresQuestionAndAnswer;
        private bool requiresUniqueEmail;
        private string applicationName;
        private string passwordStrengthRegularExpression;
        private int maxAllowedPasswordLength;
        private int maxInvalidPasswordAttempts;
        private int minRequiredNonAlphanumericCharacters;
        private int minRequiredPasswordLength;
        private int passwordAttemptWindow;
        private MembershipPasswordFormat passwordFormat;
        private UsuarioDa da = new UsuarioDa(ConfigurationManager.ConnectionStrings["RsaDb"].ConnectionString);
        #endregion

        #region "Application Name"
        public override string ApplicationName {
            get { return applicationName; }
            set { applicationName = value; }
        }
        #endregion

        #region "Password Properties"
        public override bool EnablePasswordReset {
            get { return enablePasswordReset; }
        }
        public override bool EnablePasswordRetrieval {
            get { return enablePasswordRetrieval; }
        }
        public int MaxAllowedPasswordLength {
            get { return maxAllowedPasswordLength; }
        }
        public override int MaxInvalidPasswordAttempts {
            get { return maxInvalidPasswordAttempts; }
        }
        public override int MinRequiredNonAlphanumericCharacters {
            get { return minRequiredNonAlphanumericCharacters; }
        }
        public override int MinRequiredPasswordLength {
            get { return minRequiredPasswordLength; }
        }
        public override int PasswordAttemptWindow {
            get { return passwordAttemptWindow; }
        }
        public override MembershipPasswordFormat PasswordFormat {
            get { return passwordFormat; }
        }
        public override string PasswordStrengthRegularExpression {
            get { return passwordStrengthRegularExpression; }
        }
        public override bool RequiresQuestionAndAnswer {
            get { return requiresQuestionAndAnswer; }
        }
        #endregion

        #region "Email Properties"
        public override bool RequiresUniqueEmail {
            get { return requiresUniqueEmail; }
        }
        #endregion

        #region "Configuration Methods"
        private string GetConfigValue(string configValue, string defaultValue) {
            if (string.IsNullOrEmpty(configValue))
                return defaultValue;
            return configValue;
        }
        #endregion

        #region "Initialization"
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) {
            if (config == null)
                throw new ArgumentException("Datos nulos -- en:" + System.Reflection.MethodBase.GetCurrentMethod().Name);

            if (string.IsNullOrEmpty(name))
                name = "RsaMembershipProvider";

            base.Initialize(name, config);

            applicationName = GetConfigValue(config["applicationName"], "/");
            enablePasswordReset = Convert.ToBoolean(GetConfigValue(config["enablePasswordReset"], "false"));
            enablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config["enablePasswordRetrieval"], "false"));
            requiresQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config["requiresQuestionAndAnswer"], "false"));
            requiresUniqueEmail = Convert.ToBoolean(GetConfigValue(config["requiresUniqueEmail"], "false"));
            passwordStrengthRegularExpression = GetConfigValue(config["passwordStrengthRegularExpression"], "");
            maxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
            passwordAttemptWindow = Convert.ToInt32(GetConfigValue(config["passwordAttemptWindow"], "10"));
            minRequiredNonAlphanumericCharacters = Convert.ToInt32(GetConfigValue(config["minRequiredNonAlphanumericCharacters"], "0"));
            minRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config["minRequiredPasswordLength"], "1"));
            maxAllowedPasswordLength = Convert.ToInt32(GetConfigValue(config["maxAllowedPasswordLength"], "10"));

            string pwdFormat = config["passwordFormat"];
            if (string.IsNullOrEmpty(pwdFormat))
                pwdFormat = "clear";

            switch (pwdFormat) {
                case "hashed": throw new Exception("No soporta password hasheado.");
                case "encrypted": passwordFormat = MembershipPasswordFormat.Encrypted;
                    break;
                case "clear": passwordFormat = MembershipPasswordFormat.Clear;
                    break;
                default: throw new Exception("No se encontro el formato de password.");
            }

        }
        #endregion

        #region "User and Password Methods"
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) {
            RsaMembershipUser usuario = new RsaMembershipUser("aaaaaaa");
            return usuario;
        }

        public override string GetUserNameByEmail(string email) {
            string username = string.Empty;

            try {
                
                Usuario temp = da.GetUsuarioByEmail(email);
                if (temp != null) {
                    username = temp.Username;
                }
            }
            catch (Exception) {
                // TODO: Implementar un sistema de logs
            }
            return username;
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword) {
            return false;
        }

        public override bool ValidateUser(string pUsername, string pPassword) {
            try {
                if (da.ValidateUser(pUsername, pPassword)) {
                    HttpContext.Current.Session["Rsa_Usuario"] = da.GetUsuario(pUsername);
                    return true;
                }
                else {
                    HttpContext.Current.Session["Rsa_Usuario"] = null;
                    return false;
                }
            }
            catch (Exception) {
                return false;
            }
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion
                                                  , string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) {
            RsaMembershipUser usuario = new RsaMembershipUser("");
            status = MembershipCreateStatus.Success;
            return usuario;
        }

        public override MembershipUser GetUser(string username, bool userIsOnline) {

            try {
                RsaMembershipUser usuario = new RsaMembershipUser(username);
                
                Usuario temp = da.GetUsuario(username);
                if (temp != null) {
                    usuario = GeneralParser.UsusarioToStcMembershipUser(temp);
                    return usuario;
                }
                return null;
            }
            catch (Exception) {
                return null;
            }
        }
        #endregion

        #region "Non-Implemented Methods"
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData) {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline() {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer) {
            throw new NotImplementedException();
        }

        public override string ResetPassword(string username, string answer) {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName) {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user) {
            throw new NotImplementedException();
        }
        #endregion
    }
}